package utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;

import domain.HRecord;

public final class Utility {
	
	
	

	public static String encodePassword(String password){
		MessageDigest md;
		String hash = "";
		try {
			md = MessageDigest.getInstance("SHA-1");
			md.update(password.getBytes());
			byte byteData[] = md.digest();
			
	        StringBuffer sb = new StringBuffer();
	        for (int i = 0; i < byteData.length; i++) {
	         sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
	        }
	        
	        hash = sb.toString();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return hash;
	}
	
	
	
	
	
	/******************************************************************************
	POW_: Raises x to the power y.
	- Checks function pow() in header <math.h> which sometimes gives result -1.#INF0 
	  when it calculates pow(84.799????,2).
	******************************************************************************/
/*	double pow_(double xx, double yy)
	{
		double	result	= -1E50-1;
	
		result = Math.pow(xx,yy);
		if(result < -1E50 || result > 1E50) if(xx > 0) result = Math.exp(yy * Math.log(xx));
			//System.out.println("\n     result:%.5f",result);
			//System.out.println("\n pow result:%.5f",pow(xx,yy));
			//System.out.println("\n exp result:%.5f",exp(yy * log(xx)));
		if(result < -1E50 || result > 1E50 || xx > 1E50 || yy > 1E50) 	//error check, result is probably undefined
		{
			System.out.println("\n POW_ xx:"+xx+"  yy:"+yy);
			System.out.println("\n     result:"+result);
			System.out.println("\n exp result:"+Math.exp(yy * Math.log(xx)));
			System.out.println("\n pow result:"+Math.pow(xx,yy));
			System.out.println("\n log(xx):"+Math.log(xx)+" yy * log(xx):"+yy*Math.log(xx)+" exp(yy * log(xx)):"+Math.exp(yy*Math.log(xx)));
		//	printcow(x);
			stop(1);
		}
		return result;
	}*/
	/*** end POW_ ***/
	
	
	
	/******************************************************************************
	DISCOUNT: Calculates the discount rate for a certain day into the future.
	******************************************************************************/
	public static double discount(double interestperperiod, double periods)
	{
		double	rate = 0.0;	

		rate = (1 / Math.pow((1 + interestperperiod),periods));
		return(rate);
	}
	/*** end DISCOUNT ***/
	
	
	
	/******************************************************************************
	MAX2: Returns the maximum of 2 values.
	******************************************************************************/
	public static double max2(double one, double two)
	{
		if(one > two) return one;
		else return two;
	}
	/*** end MAX2 ***/
	
	
	
	/******************************************************************************
	MAX2U: Returns the order of the maximum of 2 values.
	******************************************************************************/
	public static short max2u(double one, double two)
	{
		if(one > two) return 1;
		else return 2;
	}
	/*** end MAX2 ***/
	
	
	
	/******************************************************************************
	MAX3: Returns the maximum of 3 values.
	******************************************************************************/
	public static double max3(double one, double two, double three)
	{
		if(one > two)
			if(one > three) return one; else return three;
		if(two > three) return two; else return three;
	}
	/*** end MAX3 ***/
	
	
	
	/******************************************************************************
	MAX3U: Returns the order of the maximum of 3 values.
	******************************************************************************/
	public static int max3u(double one, double two, double three)
	{
		if(one > two)
			if(one > three) return 1; else return 3;
		if(two > three) return 2; else return 3;
	}
	/*** end MAX3U ***/
	
	
	/******************************************************************************
	MIN2: Returns the minimum of 2 values.
	******************************************************************************/
	public static double min2(double one, double two)
	{
		if(one < two) return one;
		else return two;
	}
	/*** end MIN2 ***/

	
	

	
	/******************************************************************************
	NORMAL: Calculates the cumulative probability of a value (z-score) on 
	the standard normal distribution N(0,1).
	- A.G. Adams, 1969. Computer Journal, Vol.12, 197-198. 
	  "Algorithm 39. Areas under the normal curve." Latest revision 23 January 1981.
	- Algorithm has been slightly rewritten from Fortran to C.
	- See Hill[741] and http://lib.stat.cmu.edu/apstat/66 subroutine nprob(z,p,q,pdf).
	- Function is the inverse of NORMINV().
	******************************************************************************/
	public static double normal(double zscore)
	{
		@SuppressWarnings("unused")
		double	a0 = 0.5, a1 = 0.398942280444, a2 = 0.399903438504, a3 = 5.75885480458,
				a4 = 29.8213557808, a5 = 2.62433121679, a6 = 48.6959930692,
				a7 = 5.92885724438, b0 = 0.398942280385, b1 = 3.8052E-8, b2 = 1.00000615302,
				b3 = 3.98064794E-4, b4 = 1.98615381364, b5 = 0.151679116635,
				b6 = 5.29330324926, b7 = 4.8385912808, b8 = 15.1508972451, 
				b9 = 0.742380924027, b10 = 30.789933034, b11 = 3.99019417011,
				pp = 0.0, qq = 0.0, yy = 0.0, zabs = 0.0, pdf = 0.0;
	
		zabs = Math.abs(zscore);
		if(zscore >  12.7) return(1);	
		if(zscore < -12.7) return(0);
		yy = a0 * zscore * zscore;
		pdf = Math.exp(-yy) * b0;
		if(zscore >  1.28) return(1-pdf/(zabs-b1+b2/(zabs+b3+b4/(zabs-b5+b6/(zabs+b7-b8/(zabs+b9+b10/(zabs+b11)))))));
		if(zscore < -1.28) return(pdf/(zabs-b1+b2/(zabs+b3+b4/(zabs-b5+b6/(zabs+b7-b8/(zabs+b9+b10/(zabs+b11)))))));
		if(zscore >= 0) return(1-(a0-zabs*(a1-a2*yy/(yy+a3-a4/(yy+a5+a6/(yy+a7))))));
		if(zscore <  0) return(a0-zabs*(a1-a2*yy/(yy+a3-a4/(yy+a5+a6/(yy+a7)))));
		return(pp = -1);
	}
	/*** end NORMAL ***/
	
	
	
	/******************************************************************************
	NORMALINV: Given a value of p (=cumulative probability), this function returns
	the value of x(p) (=ppnd=z-score) for the standard normal distribution.
	- J.D. Beasley and S.G. Springer, 1977. Applied Statistics, Vol.26, 118-121. 
	  "Algorithm AS 111. The percentage points of the normal distribution."
	- Beasley[737]118
	- Function is the inverse of NORMAL().
	******************************************************************************/
	public static double normalinv(double p)
	{
		double	split	=   0.42;
		double	a0 = 2.50662823884, a1 = -18.61500062529, a2 = 41.39119773534, 
				a3 = -25.44106049637, b1 = -8.47351093090, b2	= 23.08336743743, 
				b3 = -21.06224101826, b4 = 3.13082909833, c0 = -2.78718931138, 
				c1	= -2.29796479134, c2 = 4.85014127135, c3 = 2.32121276858,
				d1 = 3.54388924762, d2 = 1.63706781897;
		double	zero	=   0.0;
		double	one		=   1.0;
		double	half	=   0.5;
		@SuppressWarnings("unused")
		double	ifault, q, r, ppnd;
	
		if(p == 1.0) return  1000.0;	//own code
		if(p == 0.0) return -1000.0;	//own code
		ifault = 0;
		q = p - half;
		if(Math.abs(q) > split)
		{
			r = p;
			if(q >  zero) r = one - p;
			if(r <= zero)
			{
				ifault = 1;
				ppnd = zero;
				return ppnd;
			}
			r = Math.sqrt(-Math.log(r));
			ppnd = (((c3 * r + c2) * r + c1) * r + c0) / ((d2 * r + d1) * r + one);
			if(q < zero) ppnd = - ppnd;
			return ppnd;
		}
		r = q * q;
		ppnd = q * (((a3 * r + a2) * r + a1) * r + a0) / ((((b4 * r + b3) * r + b2) * r + b1) * r + one);
		return ppnd;
	}
	/*** end NORMALINV ***/
	

	
	public static void stop(int i){
		// Dummy Method
		// Need to erase the method
	}
	
	public static void write_msg_file(int i, double d){
		// Dummy Method
		// Need to erase the method		
	}
	
	public static void write_warm_file(int i){
		// Dummy Method
		// Need to erase the method
	}
	
	public static void system(char message[]){
		// Dummy Method
		// Need to erase the method
	}
	
	public static void strcpy(char[] message, String string) {
		// Dummy Method
		// Need to erase the method
	}
	
	public static void strcat(char[] message, char[] biofiletime) {
		// Dummy Method
		// Need to erase the method
	}

	public static void timetaken(int i) {
		// Dummy Method
		// Need to erase the method
	}

	public static int read_warm_file() {
		// Dummy Method
		// Need to erase the method
		return 0;
	}

	public static void free(HRecord h) {
		// Dummy Method
		// Need to erase the method
	}
	

	
	
	public static int roundToZeroDecimal(double val){
		return (int)Math.round(val);
	}
	
	
	
	public static double parseDouble(String value){
		double result = 0;
		try{
			result = Double.parseDouble(value);
		}catch(Exception e){
			System.out.println("Exception while parsing '"+value+"' in double.");
		}
		return result;
	}
	
	public static int parseInt(String value){
		int result = 0;
		try{
			result = Integer.parseInt(value);
		}catch(Exception e){
			System.out.println("Exception while parsing '"+value+"' in int.");
		}
		return result;
	}
	
	
	
	
	
	public static String roundToZero(double value) {
		DecimalFormat df = new DecimalFormat("#");
		return df.format(value);
	}
	
	public static String roundUptoTwo(double value) {
		DecimalFormat df = new DecimalFormat("#.##");
		return df.format(value);
	}
	
	public static String roundToExactTwo(double value) {
		DecimalFormat df = new DecimalFormat("0.00");
		return df.format(value);
	}
	
	public static String roundToZeroPCT(double value) {
		DecimalFormat df = new DecimalFormat("#");
		return df.format(100 * value) + "%";
	}
	
	
	
	
	
	
	
	
}